package cn.wolfcode.web.modules.orderinfo.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.collection.CollectionUtil;
import cn.wolfcode.web.commons.entity.LayuiPage;
import cn.wolfcode.web.commons.utils.LayuiTools;
import cn.wolfcode.web.commons.utils.PoiExportHelper;
import cn.wolfcode.web.commons.utils.SystemCheckUtils;
import cn.wolfcode.web.modules.BaseController;
import cn.wolfcode.web.modules.custinfo.entity.TbCustomer;
import cn.wolfcode.web.modules.custinfo.service.ITbCustomerService;
import cn.wolfcode.web.modules.custlinkman.entity.TbCustLinkman;
import cn.wolfcode.web.modules.custlinkman.service.ITbCustLinkmanService;
import cn.wolfcode.web.modules.log.LogModules;
import cn.wolfcode.web.modules.mail.entity.EmailDto;
import cn.wolfcode.web.modules.mail.service.EmailService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.wolfcode.web.modules.orderinfo.entity.TbOrderInfo;
import cn.wolfcode.web.modules.orderinfo.service.ITbOrderInfoService;

import link.ahsj.core.annotations.AddGroup;
import link.ahsj.core.annotations.SameUrlData;
import link.ahsj.core.annotations.SysLog;
import link.ahsj.core.annotations.UpdateGroup;
import link.ahsj.core.entitys.ApiModel;
import link.ahsj.core.exception.AppServerException;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author raolejia
 * @since 2022-10-12
 */
@Controller
@RequestMapping("orderinfo")
public class TbOrderInfoController extends BaseController {

    @Autowired
    private ITbOrderInfoService entityService;

    @Autowired
    private ITbCustomerService customerService;

    @Autowired
    private ITbCustLinkmanService linkmanService;

    @Autowired
    private EmailService emailService;

    private static final String LogModule = "TbOrderInfo";

    @GetMapping("/list.html")
    public ModelAndView list(ModelAndView mv) {
        List<TbCustomer> list = customerService.list();
        mv.addObject("custs", list);
        mv.setViewName("order/orderinfo/list");
        return mv;
    }

    @RequestMapping("/add.html")
    @PreAuthorize("hasAuthority('order:orderinfo:add')")
    public ModelAndView toAdd(ModelAndView mv) {
        List<TbCustomer> custList = customerService.list();
        mv.addObject("custList",custList);
        mv.setViewName("order/orderinfo/add");
        return mv;
    }

    @GetMapping("/{id}.html")
    @PreAuthorize("hasAuthority('order:orderinfo:update')")
    public ModelAndView toUpdate(@PathVariable("id") String id, ModelAndView mv) {
        TbOrderInfo order = entityService.getById(id);
        List<TbCustomer> custList = customerService.list();
        mv.addObject("custList",custList);
        TbCustLinkman linkman = linkmanService.lambdaQuery().eq(TbCustLinkman::getId, order.getReceiver()).one();
        mv.setViewName("order/orderinfo/update");
        order.setReceiverName(linkman.getLinkman());
        mv.addObject("obj", order);
        mv.addObject("id", id);
        return mv;
    }

    @RequestMapping("list")
    @PreAuthorize("hasAuthority('order:orderinfo:list')")
    public ResponseEntity page(LayuiPage layuiPage, String parameterName, String custId, String start, String end) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startTime = null;
        LocalDateTime endTime = null;
        if (!StringUtils.isEmpty(start)&&!StringUtils.isEmpty(end)) {
            startTime = LocalDateTime.parse(start, formatter);
            endTime = LocalDateTime.parse(end, formatter);
        }
        SystemCheckUtils.getInstance().checkMaxPage(layuiPage);
        IPage page = new Page<>(layuiPage.getPage(), layuiPage.getLimit());

        page = entityService.lambdaQuery()
                .like(!StringUtils.isEmpty(parameterName), TbOrderInfo::getProdName, parameterName)
                .eq(!StringUtils.isEmpty(custId), TbOrderInfo::getCustId, custId)
                .between(!StringUtils.isEmpty(start)&&!StringUtils.isEmpty(end), TbOrderInfo::getDeliverTime, startTime, endTime)
                .page(page);

        List<TbOrderInfo> records = page.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            records.forEach(obj -> {
                TbCustomer customer = customerService.getById(obj.getCustId());
                TbCustLinkman linkman = linkmanService.getById(obj.getReceiver());
                if (Objects.nonNull(customer) && Objects.nonNull(linkman)) {
                    obj.setReceiverName(linkman.getLinkman());
                    obj.setCustomerName(customer.getCustomerName());
                }
            });
        }
        return ResponseEntity.ok(LayuiTools.toLayuiTableModel(page));
    }

    @SameUrlData
    @PostMapping("save")
    @SysLog(value = LogModules.SAVE, module =LogModule)
    @PreAuthorize("hasAuthority('order:orderinfo:add')")
    public ResponseEntity<ApiModel> save(@Validated({AddGroup.class}) @RequestBody TbOrderInfo entity) {
        if (entity.getStatus() == 2) {
            entity.setReceiveTime(LocalDateTime.now());
        }
        if (entity.getAmounts() == null || entity.getPrice() == null ) {
            throw new AppServerException("请检查数量和价格是否填写");
        }
        if (entity.getAmounts() < 0 || entity.getPrice() < 0 ) {
            throw new AppServerException("请检查数值是否有负数");
        }
        entityService.save(entity);
        return ResponseEntity.ok(ApiModel.ok());
    }

    @SameUrlData
    @SysLog(value = LogModules.UPDATE, module = LogModule)
    @PutMapping("update")
    @PreAuthorize("hasAuthority('order:orderinfo:update')")
    public ResponseEntity<ApiModel> update(@Validated({UpdateGroup.class}) @RequestBody TbOrderInfo entity) {
        if (entity.getStatus() == 2) {
            entity.setReceiveTime(LocalDateTime.now());
        }
        if (entity.getAmounts() == null || entity.getPrice() == null ) {
            throw new AppServerException("请检查数量和价格是否填写");
        }
        if (entity.getAmounts() < 0 || entity.getPrice() < 0 ) {
            throw new AppServerException("请检查数值是否有负数");
        }
        entityService.updateById(entity);
        return ResponseEntity.ok(ApiModel.ok());
    }

    @SysLog(value = LogModules.DELETE, module = LogModule)
    @DeleteMapping("delete/{id}")
    @PreAuthorize("hasAuthority('order:orderinfo:delete')")
    public ResponseEntity<ApiModel> delete(@PathVariable("id") String id) {
        entityService.removeById(id);
        return ResponseEntity.ok(ApiModel.ok());
    }

    @RequestMapping("export")
    @SysLog(value = LogModules.EXPORT, module = LogModule)
    public void export(String parameterName, String custId, String start, String end, HttpServletResponse response) {
        List<TbOrderInfo> records = exportCommon(parameterName, custId, start, end);
        ExportParams exportParams = new ExportParams();
        //样式、字节码、内容
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, TbOrderInfo.class, records);
        try {
            PoiExportHelper.exportExcel(response, "订货单管理", workbook);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("exportToEmail")
    @SysLog(value = LogModules.EXPORT, module = LogModule)
    public ResponseEntity<ApiModel> exportToMail(String parameterName, String custId, String start, String end, String mailTo) {
        List<TbOrderInfo> list = exportCommon(parameterName, custId, start, end);
        ExportParams exportParams = new ExportParams();
        //样式、字节码、内容
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, TbOrderInfo.class, list);
        File file = new File("D:\\订货单管理.xls");
        OutputStream out = null;
        try {
            out = new FileOutputStream(file);
            workbook.write(out);
            emailService.send(new EmailDto(Collections.singletonList(mailTo),
                    "订货单管理", "这是订货单管理邮箱附件", file));
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                workbook.close();
                if (Objects.nonNull(out)) {
                    out.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return ResponseEntity.ok(ApiModel.ok());
    }

    private List<TbOrderInfo> exportCommon(String parameterName, String custId, String start, String end) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startTime = null;
        LocalDateTime endTime = null;
        if (!StringUtils.isEmpty(start)&&!StringUtils.isEmpty(end)) {
            startTime = LocalDateTime.parse(start, formatter);
            endTime = LocalDateTime.parse(end, formatter);
        }

        List<TbOrderInfo> records = entityService.lambdaQuery()
                .like(!StringUtils.isEmpty(parameterName), TbOrderInfo::getProdName, parameterName)
                .eq(!StringUtils.isEmpty(custId), TbOrderInfo::getCustId, custId)
                .between(!StringUtils.isEmpty(start)&&!StringUtils.isEmpty(end), TbOrderInfo::getDeliverTime, startTime, endTime)
                .list();

        if (CollectionUtil.isNotEmpty(records)) {
            records.forEach(obj -> {
                TbCustomer customer = customerService.getById(obj.getCustId());
                TbCustLinkman linkman = linkmanService.getById(obj.getReceiver());
                if (Objects.nonNull(customer) && Objects.nonNull(linkman)) {
                    obj.setReceiverName(linkman.getLinkman());
                    obj.setCustomerName(customer.getCustomerName());
                }
            });
        }
        return records;
    }
}
